package com.skywolf.chem.common.exception;

import com.skywolf.chem.common.enums.ResponseCodeEnum;
import com.skywolf.chem.common.sysconfig.exception.BizException;
import com.skywolf.chem.common.sysconfig.exception.FastDFSException;
import com.skywolf.chem.common.sysconfig.response.RespData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * @author Leo
 * @Description
 * @date 2019-05-16 11:38
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 参数校验异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public RespData methodArgumentNotValid(MethodArgumentNotValidException ex) {
        RespData respData = RespData.failure(ResponseCodeEnum.PARAM_ERROR);
        List<ObjectError> errors = ex.getBindingResult().getAllErrors();
        StringBuffer errorMsg = new StringBuffer();
        errors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(";"));
        log.error("---MethodArgumentNotValidException Handler--- ERROR: {}", errorMsg.toString());
        respData.setMessage(errorMsg.toString());
        return respData;
    }

    @ExceptionHandler(value = BindException.class)
    public RespData bindExceptionValid(BindException e) {
        RespData respData = RespData.failure(ResponseCodeEnum.PARAM_ERROR);
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuffer errorMsg = new StringBuffer();
        errors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(";"));
        log.error("---bindExceptionValid Handler--- ERROR: {}", errorMsg.toString());
        respData.setMessage(errorMsg.toString());
        return respData;
    }

    /**
     * 处理抛出的业务异常，封装成为响应数据RespData
     *
     * @param bizException 业务异常
     * @author Leo
     * @date 2018-11-09
     * @description 处理运行时业务异常
     */
    @ExceptionHandler({BizException.class})
    public RespData BusinessExceptionHandler(BizException bizException) {
        log.info(bizException.getMessage(), bizException);
        RespData resData = new RespData<>();
        resData.setCode(bizException.getCode());
        resData.setMessage(bizException.getMessage());
        return resData;
    }

    /**
     * 处理抛出的业务异常，封装成为响应数据RespData
     *
     * @param fastDFSException 文件操作异常
     * @author Leo
     * @date 2018-11-09
     * @description 处理文件系统异常
     */
    @ExceptionHandler({FastDFSException.class})
    public RespData FastDFSExceptionHandler(FastDFSException fastDFSException) {
        log.info(fastDFSException.getMessage(), fastDFSException);
        RespData resData = new RespData<>();
        resData.setCode(ResponseCodeEnum.FASTDFS_ERROR.getCode());
        resData.setMessage(fastDFSException.getMessage() != null ? fastDFSException.getMessage() : ResponseCodeEnum.FASTDFS_ERROR.getMessage());
        return resData;
    }

    /**
     * 处理异常，统一封装成为RespData
     *
     * @param e 异常
     *          处理所有不可知的异常
     * @author Leo
     * @date 2018-11-09
     */
    @ExceptionHandler({Exception.class})
    public RespData globalExceptionHandler(Exception e) {
        log.error(e.getMessage(), e);
        return RespData.failure(ResponseCodeEnum.SYSTEM_ERROR);
    }

}
